﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Net.Sockets;
using Newtonsoft.Json;
using System.Threading;
using System.Net;
using System.ComponentModel;

namespace WpfBeyond
{
    /// <summary>
    /// 时间段类
    /// </summary>
    public class DateTimeRange
    {
        private int id = 0;

        private DateTime beginTime;
        private DateTime endTime;
        private int playTimes = 0;//没有结束时间时有效，定时开始时间到时，需要播放的次数
        private bool hasboot = false;//标记按照次数播放的定时广播是否启动过，只能启动一次

        public DateTime BeginTime { get => beginTime; set => beginTime = value; }
        public DateTime EndTime { get => endTime; set => endTime = value; }

        public string BeginTimeStr { get => beginTime.ToString(@"yyyy-MM-dd HH:mm:ss"); }
        public string EndTimeStr { get => endTime.ToString(@"yyyy-MM-dd HH:mm:ss"); }
        public int Id { get => id; set => id = value; }
        public int PlayTimes { get => playTimes; set => playTimes = value; }
        public bool Hasboot { get => hasboot; set => hasboot = value; }

        public string Status { get { if (hasboot == false) return "未启动"; else return "已启动"; } }
    }

    public class PlayInfo
    {
        private int id = 0;
        private string fileName = "";
        private string filePath = "";
        private string sample_rate = "";

        private string duration = "";//文件时长        

        public int Id { get => id; set => id = value; }
        public string FileName { get => fileName; set => fileName = value; }
        public string FilePath { get => filePath; set => filePath = value; }
        public string Duration { get => duration; set => duration = value; }
        public double TotalSec { get => DateTime.Parse(duration).TimeOfDay.TotalSeconds; }
        public string Sample_rate { get => sample_rate; set => sample_rate = value; }
    }

    [JsonObject(MemberSerialization.OptIn)]
    public class TaskInfo : INotifyPropertyChanged
    {
        private byte[] ebmid = new byte[18] { 0xF5, 0x34, 0x12, 0x82, 0x10, 0x10, 0x00, 0x03, 0x14, 0x01, 0x02, 0x91, 0x20, 0x21, 0x07, 0x25, 0x00, 0x09 };//
        //广播类型        
        private Byte bc_type = 0;
        //事件级别        
        private Byte event_level = 0;
        //事件类型
        private byte[] event_type = new byte[5];
        private byte volume = 0;//音量
        private double mic_vol = 0.0; //输入的麦克风音量
        private double aud_vol = 0.0; //输入的音频音量

        private string content = "";//播放的内容
        private string audiopath = "";//音频或者设备路径

        private List<PlayInfo> playlist = new List<PlayInfo>();

        private string time = "";//当前播放内容的时间
        private string duration = "";//播放内容的总时长
        private string rtp = ""; //rtp地址
        private int source = 0;//音源
        private string para = "";//ffmpeg 参数        
        public Process process = null;//ffmpeg 播放进程
        private List<string> clients = new List<string>();//需要使用SN替代SOCKET，避免SOCKET中途断开
        private List<DateTimeRange> sel_dates = new List<DateTimeRange>();
        public bool Reflash = true;//初始化的时候需要刷新一次
        private int status = 0;//0:stop 1:start

        private int nowplaytimes = 0;//目前播放的次数，到达playtimes后停止
        private int playtimes = 0;//需要播放的次数

        private bool isMonitor = false;//是否在监听中
        private DateTime createtime = DateTime.Now;

        public Thread udp_thread = null;

        [JsonProperty]
        public string Ebmid_str
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 18; i++)
                {
                    sb.Append(Ebmid[i].ToString("X2"));
                }
                return sb.ToString();
            }
        }
        public string Bc_type_str
        {
            get
            {
                if (Bc_type == 1) return "发布系统演练";
                else if (Bc_type == 2) return "模拟演练";
                else if (Bc_type == 3) return "实际演练";
                else if (Bc_type == 4) return "应急广播";
                else if (Bc_type == 5) return "日常广播";
                else return "保留";
            }
        }

        public string Event_level_str
        {
            get
            {
                if (Event_level == 1) return "1 级（特别重大）";
                else if (Event_level == 2) return "2 级（重大）";
                else if (Event_level == 3) return "3 级（较大）";
                else if (Event_level == 4) return "4 级（一般）";
                else return "保留";
            }
        }

        public string Status_str
        {
            get
            {
                if (status == 0) return "停止";
                else return "开始";
            }
        }
        public string Source_str { get { if (source == 0) return "麦克风"; else return "音频文件"; } }

        public string Monitor_Str { get { if (IsMonitor == false) return "监听"; else return "监听中"; } }

        public string CreateTimeStr { get => createtime.ToString(@"yyyy-MM-dd HH:mm:ss"); }

        public string Progress
        {
            get
            {
                return time + "/" + duration;
            }
        }

        [JsonProperty]
        public byte[] Ebmid { get => ebmid; set => ebmid = value; }
        [JsonProperty]
        public byte[] Event_type { get => event_type; set => event_type = value; }
        [JsonProperty]
        public byte Volume { get => volume; set => volume = value; }
        [JsonProperty]
        public string Content { get => content; set { content = value; OnPropertyChanged("Content"); } }
        [JsonProperty]
        public string Time { get => time; set { time = value; OnPropertyChanged("Progress"); } }
        [JsonProperty]
        public string Duration { get => duration; set => duration = value; }
        [JsonProperty]
        public List<string> Clients { get => clients; set => clients = value; }
        [JsonProperty]
        public List<DateTimeRange> Sel_dates { get => sel_dates; set => sel_dates = value; }
        [JsonProperty]
        public byte Bc_type { get => bc_type; set => bc_type = value; }
        [JsonProperty]
        public byte Event_level { get => event_level; set => event_level = value; }
        [JsonProperty]
        public int Status { get => status; set => status = value; }
        [JsonProperty]
        public string Audiopath { get => audiopath; set => audiopath = value; }
        [JsonProperty]
        public string Rtp { get => rtp; set => rtp = value; }

        /// <summary>
        /// 获取播放参数
        /// </summary>
        public string Para
        {
            get
            {
                if (source == 0)//麦克风
                {
                    return string.Format("-protocol_whitelist udp,rtp -fflags nobuffer -f dshow -i audio=\"{0}\" -acodec mp3 -f rtp {1}", audiopath, rtp);
                }
                else if(source == 1)//音频
                {
                    HashSet<string> hs = new HashSet<string>();

                    foreach (PlayInfo p in playlist)
                    {
                        hs.Add(p.FilePath);
                    }
                    string str = "concat:" + string.Join("|", hs);

                    string para = "";

                    if (sel_dates.Count == 0)
                    {
                        //para = string.Format("-vn -re -i \"{0}\" -acodec mp3 -f mpegts udp://127.0.0.1:5000", str);
                        if (LocalSetting.Items.Ffmpeg_mode == 0)//RTP
                        {
                            para = string.Format("-vn -re -i \"{0}\" -acodec mp3 -f rtp {1}", str, rtp);
                        }
                        else//UDP
                        {
                            para = string.Format("-vn -re -i \"{0}\" -acodec mp3 -f mpegts {1}", str, rtp.Replace("@", "127.0.0.1"));
                        }
                    }
                    else
                    {//定时广播
                        if (PlayTimes > 0)
                        {
                            para = string.Format("-vn -stream_loop {0} -re -i \"{1}\" -acodec mp3 -f rtp {2}", PlayTimes, str, rtp);
                        }
                        else
                        {
                            para = string.Format("-vn -stream_loop -1 -re -i \"{0}\" -acodec mp3 -f rtp {1}", str, rtp);
                        }
                    }

                    return para;

                    //return string.Format("-protocol_whitelist file,udp,rtp -vn -stream_loop -1 -re -i \"{0}\" -acodec mp3 -f rtp {1}", audiopath, rtp);
                }
                else//混音
                {
                    //ffmpeg -protocol_whitelist udp,rtp -fflags nobuffer -f dshow -i audio="Mic in at rear panel (Pink) (Re" -i "郝云 - 活着.mp3" -filter_complex "[0]volume=1[a];[1]volume=0.5[b];[a][b]amix=inputs=2:duration=first:dropout_transition=2" -acodec mp3 -f rtp rtp://224.2.2.2:5000

                    HashSet<string> hs = new HashSet<string>();

                    foreach (PlayInfo p in playlist)
                    {
                        hs.Add(p.FilePath);
                    }
                    string str = "concat:" + string.Join("|", hs);

                    StringBuilder sb = new StringBuilder();
                    sb.Append("-protocol_whitelist udp,rtp -fflags nobuffer -f dshow");
                    sb.Append(string.Format(" -i audio=\"{0}\"", audiopath));
                    sb.Append(string.Format(" -stream_loop -1 -i \"{0}\"", str));

                    sb.Append(string.Format(" -filter_complex \"[0]volume={0}[a];[1]volume={1}[b];[a][b]amix=inputs=2:duration=first:dropout_transition=2\" -acodec mp3 -f rtp {2}", mic_vol, aud_vol, rtp));

                    return sb.ToString();
                }
            }
            set => para = value;
        }
        [JsonProperty]
        public int Source { get => source; set => source = value; }
        [JsonProperty]
        public List<PlayInfo> Playlist { get => playlist; set => playlist = value; }
        public bool IsMonitor { get => isMonitor; set { isMonitor = value; OnPropertyChanged("Monitor_Str"); } }
        public int PlayTimes { get => playtimes; set => playtimes = value; }
        public int NowPlayTimes { get => nowplaytimes; set => nowplaytimes = value; }
        [JsonProperty]
        public DateTime CreateTime { get => createtime; set => createtime = value; }
        public double Mic_vol { get => mic_vol; set => mic_vol = value; }
        public double Aud_vol { get => aud_vol; set => aud_vol = value; }

        public TaskInfo()
        {

        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public void GenEBMID()
        {
            //生成EBM ID
            DateTime dt = DateTime.Now;
            string datestr = dt.Year.ToString() + dt.Month.ToString("D2") + dt.Day.ToString("D2");
            byte[] datebcd = Common.STR2BCD(datestr);
            Array.Copy(datebcd, 0, Ebmid, 12, 4);

            //流水号自增1
            short flowid = Common.ebmid_flowid();
            byte[] flowidbcd = Common.STR2BCD(flowid.ToString("D4"));
            Ebmid[16] = flowidbcd[0];// 
            Ebmid[17] = flowidbcd[1];//
        }

        private void Output(object sendProcess, DataReceivedEventArgs output)
        {
            if (!String.IsNullOrEmpty(output.Data))
            {
                LogHelp.Info(output.Data);

                if (output.Data.IndexOf("Duration:") >= 0)
                {
                    if (output.Data.IndexOf("N/A") >= 0)
                    {
                        //  Duration: N/A, start: 282762.870000, bitrate: 1411 kb/s
                        duration = "";
                    }
                    else
                    {
                        duration = output.Data.Substring(output.Data.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00").Length);
                    }
                }

                //size=      86kB time=00:00:05.46 bitrate= 128.4kbits/s speed=0.983x
                if (output.Data.IndexOf("time=") >= 0)
                {
                    if (duration == "") return;

                    string _Time = output.Data.Substring(output.Data.IndexOf("time=") + ("time=").Length, ("00:00:00").Length);

                    double s1 = TimeSpan.Parse(_Time).TotalSeconds;
                    double s2 = TimeSpan.Parse(duration).TotalSeconds;
                    double sec = s1 % s2;
                    if (s2 > 0) nowplaytimes = (int)(s1 / s2);
                    double s3 = 0;

                    foreach (PlayInfo p in playlist)
                    {
                        if (sec >= s3 && sec <= s3 + p.TotalSec)
                        {
                            Content = p.FileName;
                            break;
                        }
                        s3 += p.TotalSec;
                    }

                    TimeSpan ts = new TimeSpan(0, 0, (int)sec);
                    Time = ts.ToString(@"hh\:mm\:ss");
                }

            }
        }

        private void udp_work()
        {
            EndPoint ep = null;
            Socket socket_listen = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint iep = new IPEndPoint(IPAddress.Any, 5000);
            ep = (EndPoint)iep;
            socket_listen.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            Socket socket_send = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            socket_listen.Bind(iep);

            byte[] b = new byte[1024 * 4];
            int n = 0;

            List<EndPoint> ep_list = new List<EndPoint>();

            foreach (string sn in clients)
            {
                IPAddress remoteIp = IPAddress.Parse(Devices.Get_Device(sn).ipaddr);
                IPEndPoint iep_client = new IPEndPoint(remoteIp, 5000);
                ep = (EndPoint)iep_client;
                ep_list.Add(ep);
                //socket_listen.SendTo(heartbeat_response, heartbeat_response.Length, SocketFlags.None, ep);
            }

            while (true)
            {
                n = socket_listen.ReceiveFrom(b, ref ep);

                foreach (EndPoint ep1 in ep_list)
                {
                    socket_send.SendTo(b, n, SocketFlags.None, ep1);
                }

                Thread.Sleep(1);
            }
        }

        private void Processffmpeg(Process p)
        {
            //是否使用操作系统shell启动
            p.StartInfo.UseShellExecute = false;
            //不显示程序窗口
            p.StartInfo.CreateNoWindow = true;

            p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流

            p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN            
            p.EnableRaisingEvents = true;
            p.Exited += new EventHandler(P_Exited);

            if (LocalSetting.Items.Ffmpeg_mode == 1)
            {
                udp_thread = new Thread(new ThreadStart(udp_work));
                udp_thread.IsBackground = true;//设置为后台线程，否则即使主程序界面关闭了，程序也不会真正关闭，子线程会继续执行下去
                udp_thread.Start();
            }

            p.Start();
            Status = 1;

            p.BeginErrorReadLine();//开始异步读取 
        }

        private void P_Exited(object sender, EventArgs e)
        {
            Stop();
            if (sel_dates.Count == 0)
            {
                TaskFactory.Remove_TaskInfo(this);
            }

        }

        /// <summary>
        /// 启动任务
        /// </summary>
        public void Start()
        {
            int count = 0;//发送客户端数量
            IpPacket bc = null;

            bc = new IpPacket(0x1);

            //拷贝任务EBM ID
            Array.Copy(this.Ebmid, bc.body.p_play.ebmid, 18);

            bc.body.p_play.bc_type = this.Bc_type;
            bc.body.p_play.event_level = this.Event_level;

            bc.body.p_play.volume = this.volume;
            bc.body.p_play.aux_num = 1;
            bc.body.p_play.aux_type = 61;

            //RTP地址需要外部根据TASKLIST获取，并赋值
            bc.body.p_play.aux_content = System.Text.Encoding.Default.GetBytes(this.Rtp);

            bc.body.p_play.aux_len = (ushort)bc.body.p_play.aux_content.Length;

            bc.encode();

            for (int i = 0; i < Clients.Count; i++)
            {
                Device d = Devices.Get_Device(Clients[i]);
                if (d == null) continue;
                if (d.socket == null) continue;

                d.ReStart_times = 0;
                d.ReStart_dateTimes = DateTime.Now;
                //通过序列号查找当前设备的SOCKET句柄
                d.socket.Send(bc.data, bc.data_len, SocketFlags.None);
                //设备添加相应 TASK
                d.tasklist.Add(this);
                //累计发送客户端的数量
                count++;
            }
            //没有客户端存在
            if (count == 0) return;

            Process p = new Process();

            string FFmpegPath = @"ffmpeg.exe";
            p.StartInfo.FileName = FFmpegPath;
            p.StartInfo.Arguments = Para;
            this.process = p;

            Processffmpeg(p);
        }


        public void Stop()
        {
            IpPacket bc = new IpPacket(0x2);

            try
            {
                Array.Copy(Ebmid, bc.body.p_stop.ebmid, 18);
                bc.encode();

                foreach (string sn in Clients)
                {
                    Devices.Get_Device(sn).socket.Send(bc.data, bc.data_len, SocketFlags.None);
                    //s.Send(bc.data, bc.data_len, SocketFlags.None);
                    //设备删除相应TASK
                    Devices.Get_Device(sn).tasklist.Remove(this);
                }

                //状态置为停止
                this.Status = 0;

                if (process != null)
                {
                    if (process.HasExited == false)
                    {
                        process.Kill();
                        process.WaitForExit();
                        //process.Close();
                        //process.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelp.Error(ex.ToString());
            }
        }

    }

    public class TaskFactory
    {
        public static object _lock = new object();

        public static List<TaskInfo> list = new List<TaskInfo>();

        //运行中的任务不能添加到history中，否则会影响界面刷新
        public static List<TaskInfo> history = new List<TaskInfo>();

        public static TaskInfo GetTaskInfo(string ebmid)
        {
            int Index = 0;

            lock (_lock)
            {
                for (Index = list.Count - 1; Index >= 0; Index--)
                {
                    if (list[Index] == null) break;

                    if (list[Index].Ebmid_str == ebmid)
                    {
                        return list[Index];
                    }
                }
            }
            return null;
        }


        public static bool IsReflash()
        {
            int Index = 0;
            bool Reflash = false;

            lock (_lock)
            {
                for (Index = list.Count - 1; Index >= 0; Index--)
                {
                    if (list[Index] == null) break;

                    if (list[Index].Reflash == true)
                    {
                        Reflash = true;
                        list[Index].Reflash = false;
                    }
                }
            }
            return Reflash;
        }

        public static TaskInfo GetPlayTask()
        {
            int Index = 0;

            lock (_lock)
            {
                for (Index = list.Count - 1; Index >= 0; Index--)
                {
                    if (list[Index] == null) continue;
                    if (list[Index].Status == 1) continue;//已经启动任务

                    if (list[Index].Sel_dates.Count == 0)
                    {//立即播放
                        //list[Index].PlayNext();
                    }
                    else
                    {//定时播放
                        //在任务范围之内
                        foreach (DateTimeRange dt in list[Index].Sel_dates)
                        {
                            if (DateTime.Now > dt.BeginTime && DateTime.MinValue == dt.EndTime && dt.Hasboot == false)//按照次数的定时广播
                            {
                                list[Index].NowPlayTimes = 0;
                                list[Index].PlayTimes = dt.PlayTimes;
                                dt.Hasboot = true;//启动一次后就不能再启动了

                                return list[Index];
                            }
                            if (DateTime.Now > dt.BeginTime && DateTime.Now < dt.EndTime)//按照时间范围的定时广播
                            {
                                return list[Index];
                            }
                        }
                    }
                }
            }
            return null;
        }


        public static TaskInfo GetStopTask()
        {
            int Index = 0;
            bool founded = false;

            lock (_lock)
            {
                for (Index = list.Count - 1; Index >= 0; Index--)
                {
                    if (list[Index] == null) continue;
                    if (list[Index].Status == 0) continue;//未启动不判断
                    if (list[Index].Sel_dates.Count == 0) continue;//立即播放，不判断
                    founded = false;

                    foreach (DateTimeRange dt in list[Index].Sel_dates)
                    {
                        if (DateTime.Now > dt.BeginTime
                            && DateTime.MinValue == dt.EndTime
                            && list[Index].NowPlayTimes < list[Index].PlayTimes)
                        {
                            founded = true;
                            return null;
                        }

                        if (DateTime.Now > dt.BeginTime
                            && DateTime.Now < dt.EndTime)
                        {
                            founded = true;
                            return null;
                        }
                    }

                    //否不在存在指定范围内
                    if (founded == false)
                    {
                        return list[Index];
                    }

                }
            }
            return null;
        }

        public static void StopAll()
        {
            int Index = 0;

            lock (_lock)
            {
                for (Index = list.Count - 1; Index >= 0; Index--)
                {
                    if (list[Index] == null) continue;
                    if (list[Index].process == null) continue;//没有FFMPEG进程

                    list[Index].Stop();
                    //list.RemoveAt(Index); 在STOP里面删除DEVICE的TASK时，list也就删除了
                }
            }
        }

        /// <summary>
        /// 删除过期的任务
        /// </summary>        
        public static void DelExpireTask()
        {
            int Index = 0;
            bool founded = false;

            lock (_lock)
            {
                for (Index = list.Count - 1; Index >= 0; Index--)
                {
                    if (list[Index] == null) continue;
                    if (list[Index].Status == 1) continue;//启动不判断
                    if (list[Index].Sel_dates.Count == 0) continue;//立即播放，不判断

                    founded = false;

                    foreach (DateTimeRange dt in list[Index].Sel_dates)
                    {
                        //按照次数定时的，还有未启动的
                        if (DateTime.MinValue == dt.EndTime
                            && dt.Hasboot == false)
                        {
                            founded = true;
                            break;
                        }
                        //存在结束时间比当前时间大的，即未播放
                        if (DateTime.Now < dt.EndTime)
                        {
                            founded = true;
                            break;
                        }

                    }

                    if (founded == false)
                    {
                        list.RemoveAt(Index);
                    }
                }
            }
        }

        /// <summary>
        /// 检查已经启动的任务中，设备状态未正常播放的重新开播
        /// </summary>
        public static void Check_TaskInfo()
        {
            int Index = 0;

            lock (_lock)
            {
                for (Index = list.Count - 1; Index >= 0; Index--)
                {
                    if (list[Index] == null) continue;
                    if (list[Index].Status == 0) continue;//已经启动的                    

                    foreach (string sn in list[Index].Clients)
                    {
                        Device d = Devices.Get_Device(sn);
                        if (d == null) continue;
                        if (d.socket == null) continue;

                        if (d.Status == 1 && d.ReStart_times < 5 && d.ReStart_dateTimes.Subtract(DateTime.Now).Duration().TotalMinutes > 2)//空闲
                        {
                            //2分钟内不重复请求，最多请求5次
                            d.ReStart_times++;
                            d.ReStart_dateTimes = DateTime.Now;

                            IpPacket bc = null;

                            bc = new IpPacket(0x1);

                            //拷贝任务EBM ID
                            Array.Copy(list[Index].Ebmid, bc.body.p_play.ebmid, 18);

                            bc.body.p_play.bc_type = list[Index].Bc_type;
                            bc.body.p_play.event_level = list[Index].Event_level;

                            bc.body.p_play.volume = list[Index].Volume;
                            bc.body.p_play.aux_num = 1;
                            bc.body.p_play.aux_type = 61;

                            //RTP地址需要外部根据TASKLIST获取，并赋值
                            bc.body.p_play.aux_content = System.Text.Encoding.Default.GetBytes(list[Index].Rtp);

                            bc.body.p_play.aux_len = (ushort)bc.body.p_play.aux_content.Length;

                            bc.encode();

                            d.socket.Send(bc.data, bc.data_len, SocketFlags.None);
                            //设备添加相应 TASK
                            d.tasklist.Add(list[Index]);

                        }

                    }

                }
            }
        }

        public static bool Add_TaskInfo(TaskInfo t)//wangm:2020-6-2
        {
            //bool bFlag = false;
            int Index = 0;

            lock (_lock)
            {
                for (Index = list.Count - 1; Index >= 0; Index--)
                //foreach (Device de in this)
                {
                    if (list[Index] == null) break;
                }

                list.Add(t);

            }
            return true;
        }

        public static void Remove_TaskInfo(TaskInfo t)
        {
            lock (_lock)
            {
                t = list.Find(o => o == t);
                if (t == null)
                {
                    return;
                }

                list.Remove(t);

                //避免程序一直运行到第二天，历史记录存到前一天
                history = Common.LoadHistoryJson();
                if (history == null)
                {
                    history = new List<TaskInfo>();
                }
                history.Insert(0, t);
                //历史记录，倒序排列         
                Common.SaveJson(LocalSetting.History_JsonFileName, history);
                Common.reflash_task = true;
            }
        }

        public static void SetDuration(Process p, string dur)
        {
            int i = 0;
            lock (_lock)
            {
                try
                {
                    for (i = 0; i < list.Count; i++)
                    {
                        if (list[i].process == p)
                        {
                            list[i].Duration = dur;
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelp.Error(ex.ToString());
                }
            }
        }

        public static void SetTime(Process p, string time)
        {
            int i = 0;
            lock (_lock)
            {
                for (i = 0; i < list.Count; i++)
                {
                    if (list[i].process == p)
                    {
                        list[i].Time = time;
                        break;
                    }
                }
            }
        }

        public static string GetRtp()
        {
            string rtp = "";
            if (LocalSetting.Items.Ffmpeg_mode == 0)
            {
                rtp = LocalSetting.Items.Ffmpeg_rtp;
            }
            else
            {
                rtp = LocalSetting.Items.Ffmpeg_udp;
            }

            lock (_lock)
            {
                TaskInfo t = list.FindLast(t => t.Rtp != "");

                if (t == null) return rtp;

                rtp = t.Rtp;

                string port = rtp.Substring(rtp.LastIndexOf(":") + 1, rtp.Length - rtp.LastIndexOf(":") - 1);

                int iport = Convert.ToInt32(port);
                iport++;

                rtp = rtp.Substring(0, rtp.LastIndexOf(":") + 1) + iport.ToString();
            }

            return rtp;
        }


    }

}
